package com.zmn.oms.business.impl.messageV1.wechat;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.base.pilot.common.dto.pilot.PilotCheckQuery;
import com.zmn.base.pilot.common.enums.PilotTypeEnum;
import com.zmn.base.price.common.dro.tariff.TariffDRO;
import com.zmn.base.price.dubbo.interfaces.tariff.TariffRemoteService;
import com.zmn.biz.engineer.common.dro.health.EngineerHealthLogoDRO;
import com.zmn.biz.engineer.dubbo.interfaces.health.EngineerHealthListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.amount.AmountUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.encode.EncodeUtil;
import com.zmn.common.utils.math.MoneyUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.oms.business.impl.messageV1.common.AbstractBaseMessage;
import com.zmn.oms.business.interfaces.messageV1.common.MessageGetSendInfoService;
import com.zmn.oms.business.interfaces.warranty.OrderWarrantyBService;
import com.zmn.oms.common.constant.MessageConsts;
import com.zmn.oms.common.constant.MessageRuleIdConsts;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderQuotation3Constant;
import com.zmn.oms.model.dto.messageV1.SendMessageParams;
import com.zmn.oms.model.dto.messageV1.WeChatMessageDTO;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.orderappbind.OrderThirdAppBind;
import com.zmn.oms.model.entity.pay.OrderPay;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.quotation3.OrderFault;
import com.zmn.oms.model.entity.quotation3.OrderMaintainItem;
import com.zmn.oms.model.entity.visit.OrderVisit;
import com.zmn.oms.model.entity.visit.OrderVisitQuery;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.warranty.WarrantyVO;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.pay.OrderPayService;
import com.zmn.oms.services.interfaces.quotation3.OrderFaultService;
import com.zmn.oms.services.interfaces.quotation3.OrderMaintainItemService;
import com.zmn.oms.services.interfaces.visit.OrderVisitService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.pay.common.constant.PayConsts;
import com.zmn.saas.common.dto.wechat.WeixinUserInfoDRO;
import com.zmn.saas.dubbo.interfaces.qrcode.PrivateQrCodeListRemoteService;
import com.zmn.saas.dubbo.interfaces.quotation.QuotationListRemoteService;
import com.zmn.ums.dubbo.interfaces.weixincp.WeixincpUserListRemoteService;
import com.zmn.uuc.common.dro.user.UserDetailDRO;
import com.zmn.uuc.dubbo.interfaces.user.UserListRemoteService;
import com.zmn.vas.common.dro.member.MemberDRO;
import com.zmn.vas.dubbo.interfaces.member.MemberListRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 类描述：
 *
 * @author yule
 * @date 2020/6/12 19:22
 */
@Slf4j
public abstract class AbstractMessageSendWeChat extends AbstractBaseMessage {
    protected Logger logger = LoggerFactory.getLogger(AbstractMessageSendWeChat.class);

    @Reference(version = com.zmn.ums.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    protected WeixincpUserListRemoteService weixincpUserListRemoteService;
    @Reference(version = com.zmn.saas.dubbo.constant.SaasDubboConsts.INTERFACE_VERSION, check = false)
    protected PrivateQrCodeListRemoteService privateQrCodeListRemoteService;
    @Reference(version = com.zmn.saas.dubbo.constant.SaasDubboConsts.INTERFACE_VERSION, check = false)
    protected QuotationListRemoteService quotationListRemoteService;
    @Autowired
    protected MessageGetSendInfoService messageGetSendInfoService;
    @Autowired
    protected OrderWorkService orderWorkService;
    @Autowired
    protected OrderDetailService orderDetailService;
    @Autowired
    protected OrderWarrantyService orderWarrantyService;
    @Autowired
    protected OrderWarrantyBService orderWarrantyBService;
    @Autowired
    protected OrderPayService orderPayService;
    @Autowired
    protected OrderMaintainItemService orderMaintainItemService;
    @Autowired
    protected OrderFaultService orderFaultService;
    @Autowired
    protected OrderVisitService orderVisitService;

    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    protected TariffRemoteService tariffRemoteService;

    @DubboReference(version = com.zmn.uuc.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    protected UserListRemoteService userListRemoteService;
    @DubboReference(version = com.zmn.vas.dubbo.consts.VasDubboConsts.INTERFACE_VERSION, check = false)
    protected MemberListRemoteService memberListRemoteService;

    @DubboReference(version = com.zmn.biz.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerHealthListRemoteService engineerHealthListRemoteService;

    // 商品详情页：/subPackages/product/detail?id=产品id      3.0
    @Value("${oms.wechat.detail.quotation3.url:/subPackages/product/detail?id=%s}")
    private String productDetailWechatQuotation3Url;
    // 订单详情页：/subPackages/order/detail/index?id={$order_id}      2.0     和非计价器订单
    @Value("${oms.wechat.detail.url:/subPackages/order/detail/index?id=%s}")
    private String orderDetailWechatUrl;

    // 非会员完成消息附加内容
    private final static String COMPLETE_CONTENT_NORMAL = "【回复关键字“礼包”，立领500元礼包】";

    // 会员完成消息附加内容
    private final static String COMPLETE_CONTENT_MEMBER = "您还有会员券未用，有需要记得找小啄哦～";

    /**
     * 获取发送微信消息的必要条件信息
     *
     * @param params
     * @return
     */
    protected WeChatMessageDTO getWeChatSendInfo(SendMessageParams params) {
        if (StringUtils.isBlank(params.getThirdAppId())) {
            logger.info("[{}]获取第三方信息为空", params.getWorkId());
            return null;
        }
        if (NumberUtil.isNullOrZero(params.getSendUserId())) {
            logger.info("#oms#订单号={}，发送用户{}不存在", params.getWorkId(), params.getSendUserId());
            return null;
        }

        String openId = messageGetSendInfoService.getWeChatOpenIdAndCheckUserSubscribe(params.getOrderId(), params.getSendUserId(), params.getThirdAppId());
        if (StringUtils.isBlank(openId)) {
            logger.info("未找到工单号={}，用户userId={}的openId 或 用户未关注", params.getOrderId(), params.getSendUserId());
            return null;
        }

        OrderWork orderWork = params.getOrderWork();
        WeChatMessageDTO message = WeChatMessageDTO.builder()
                .orderId(params.getOrderId())
                .ruleId(params.getRuleId())
                .objectId(String.valueOf(params.getSendUserId()))
                .openId(openId)
                .skipType(GlobalConsts.YES)// 默认都是跳转到小程序
                .thirdAppId(params.getThirdAppId())
                .channelId(String.valueOf(orderWork.getChannelId()))
                .cityId(String.valueOf(orderWork.getCityId()))
                .build();

        if (Objects.equals(params.getRuleId(), MessageConsts.ZMN_MSG_RULEID_QUESTIONNAIRE)) {
            // 跳转到 h5
            message.setSkipType(GlobalConsts.NO);
        }

        return message;
    }

    /**
     * 获取微信用户信息(用于直接发送微信逻辑)
     *
     * @param orderId    订单号
     * @param sendUserId 发送用户Id
     * @param openId     openId，非指定openId可不传
     * @return
     */
    protected WeChatMessageDTO getWeChatMessageDesignatedInfo(Long orderId, Integer ruleId, Long sendUserId, String openId, Long objectId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        if (Objects.isNull(orderWork)) {
            return null;
        }

        OrderThirdAppBind orderThirdAppBind = messageGetSendInfoService.getOrderWeChatBindInfoForOrderBy(orderId, orderWork.getPlatWork());
        if (Objects.isNull(orderThirdAppBind) || StringUtils.isBlank(orderThirdAppBind.getThirdAppId())) {
            logger.info("订单号{}，未找到绑定公众号信息，发送条件不满足", orderWork.getWorkId());
            return null;
        }

        if (StringUtils.isBlank(openId)) {
            openId = messageGetSendInfoService.getWeChatOpenIdByUserIdAndAppId(orderId, sendUserId, orderThirdAppBind.getThirdAppId());
        }

        if (StringUtils.isBlank(openId)) {
            logger.info("未找到工单号={}，用户userId={}的openId ", orderId, sendUserId);
            return null;
        }
        // 判断当前用户是否关注公众号
        boolean isUserSubscribe = isUserSubscribe(orderId, openId, orderThirdAppBind.getThirdAppId());
        logger.info("工单号{}send，判断当前用户openId[{}],是否关注公众号结果[{}]", orderWork.getOrderId(), openId, isUserSubscribe);
        if (!isUserSubscribe) {
            return null;
        }

        OrderProduct orderProduct = getProduct(orderId);
        // 处理指定模板消息参数
        // 定金待支付，完成待支付  {$order_id}  {$amount}  {$order_time}-下单时间
        // 计价器定价/计价器变更   {$productName}， {$order_id}   {$visit_time}
        // 保修卡 {$warranty_id} ：{$useful_days}天

        // 组装发送参数
        HashMap<String, String> smsMap = new HashMap<>();
        smsMap.put("order_id", String.valueOf(orderId));
        smsMap.put("order_time", DateUtil.toString(orderWork.getReceiveTime(), "MM月dd日 HH时mm分"));
        smsMap.put("product_name", orderProduct.getShowProductName());
        if (NumberUtil.isNotNullOrZero(orderWork.getTotalAmount())) {
            smsMap.put("amount", MoneyUtil.parseToYuanStr(orderWork.getTotalAmount()));
        }

        if (Objects.nonNull(orderWork.getVisitTime())) {
            smsMap.put("visit_time", DateUtil.toString(orderWork.getVisitTime(), "MM月dd日 HH时mm分"));
            smsMap.put("home_time", DateUtil.toString(orderWork.getVisitTime(), "MM月dd日 HH时mm分"));
            smsMap.put("charge_time", DateUtil.toString(orderWork.getVisitTime(), "MM月dd日 HH时mm分"));
        }

        // 定金带支付
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_DEPOSIT_PAY, ruleId)) {
            smsMap.put("amount", NumberUtil.isNotNullOrZero(orderWork.getDepositAmount()) ? MoneyUtil.parseToYuanStr(orderWork.getDepositAmount()) + "" : "0.00");
            smsMap.put("open_id", openId);
        }

        // 完成带支付
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_ORDER_PAY, ruleId)) {
            if (NumberUtil.isNotNullOrZero(objectId)) {
                smsMap.put("orderPayId", String.valueOf(objectId));
                smsMap.put("payAmountType", String.valueOf(OrderConsts.ORDER_ACCEPTANCE_TYPE_PROGRESS));
                OrderPay orderPay = orderPayService.findOrderPayByKeySrcMaster(orderId, objectId);
                if (Objects.isNull(orderPay)) {
                    return null;
                }
                smsMap.put("amount", MoneyUtil.parseToYuanStr(orderPay.getAmount()));
            } else {
                smsMap.put("payAmountType", String.valueOf(OrderConsts.ORDER_ACCEPTANCE_TYPE_PAYMENT));
                smsMap.put("amount", NumberUtil.isNotNullOrZero(orderWork.getMasterAmount()) ? MoneyUtil.parseToYuanStr(orderWork.getMasterAmount()) + "" : "0.00");
            }
        }

        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_WARRANTY_CARD, ruleId) || Objects.equals(MessageRuleIdConsts.CNHB_MSG_RULEID_WARRANTY_CARD, ruleId)) {
            WarrantyVO warrantyVO = orderWarrantyBService.findWarrantyVOByOrderId(orderWork.getOrderId());
            if (Objects.nonNull(warrantyVO)) {
                smsMap.put("warranty_id", String.valueOf(warrantyVO.getCode()));
                smsMap.put("useful_days", String.valueOf(warrantyVO.getPeriod()));
                smsMap.put("warranty_code", getStrEnCode(warrantyVO.getCode()));
            }
        }

        // 尾款验收消息或者计价器3.0验收消息
        if (Objects.equals(MessageConsts.ZMN_WECHAT_MSG_RULEID_ORDER_ACCEPTANCE_PAYMENT, ruleId)
                || Objects.equals(MessageConsts.ZMN_WECHAT_MSG_RULE_ID_QUOTATION_THREE_PAYMENT, ruleId)) {
            smsMap.put("service_time", DateUtil.dateFormatToString(orderWork.getDutyTime(),"MM月dd日 HH时mm分"));
            smsMap.put("acceptanceId", String.valueOf(objectId));
        }

        // 定金确认消息
        if (Objects.equals(MessageConsts.ZMN_WECHAT_MSG_RULEID_ORDER_ACCEPTANCE_DEPOSIT, ruleId)) {
            smsMap.put("acceptanceId", String.valueOf(objectId));
            OrderVisitQuery query = new OrderVisitQuery();
            query.setOrderId(orderId);
            query.setAcceptanceId(objectId);
            OrderVisit orderVisit = orderVisitService.findOrderVisitByQuerySrcMaster(query);
            if (Objects.isNull(orderVisit.getAmount())) {
                smsMap.put("amount", "0");
            } else {
                smsMap.put("amount", MoneyUtil.parseToYuanStr(orderVisit.getAmount()));
            }
        }

        // 确认故障现象
        if (Objects.equals(MessageConsts.ZMN_MSG_RULEID_USER_FAULT_REPORT, ruleId)) {
            smsMap.put("late_yesno_wx", NumberUtil.isNullOrZero(orderWork.getDiscountActivityId()) ? "若上门延误，服务费减免20元" : Character.toString((char) 12288));
            smsMap.put("pay_yesno", !Objects.equals(orderWork.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_ADVANCE_PAY) ?
                    "，开通Z+钻卡会员，享全年10大特权，一单回本" : Character.toString((char) 12288));
            smsMap.put("product_name", orderProduct.getProductName());
            smsMap.put("visit_time", DateUtil.dateFormatToString(orderWork.getVisitTime(),"MM月dd日 HH时mm分"));
            smsMap.put("duty_time", DateUtil.dateFormatToString(orderWork.getDutyTime(),"MM月dd日 HH时mm分"));
        }

        // 确认检修报告
        if (Objects.equals(MessageConsts.ZMN_MSG_RULEID_CONFIRM_CHECK_REPORT, ruleId)) {
            List<OrderMaintainItem> maintainItems = orderMaintainItemService.listByOrderId(orderId);
            List<OrderFault> orderFaults = orderFaultService.listByOrderId(orderId);

            Integer faultLevel = orderFaults.stream().map(OrderFault::getFaultLevel).max(Integer::compareTo).get();

            smsMap.put("project_number", String.valueOf(maintainItems.size()));
            smsMap.put("fault_level", OrderQuotation3Constant.getFaultLevel(faultLevel));

            // 主从同步会导致amount没有值的问题？
            // 处理已付金额
            Integer factAmount = 0;
            if (Objects.equals(orderWork.getChannelPrepayStatus(), PayConsts.PAY_STATUS_DONE) && !NumberUtil
                    .isNullOrZero(orderWork.getChannelPrepayAmount())) {
                factAmount = factAmount + orderWork.getChannelPrepayAmount().intValue();
            }
            if (Objects.equals(orderWork.getPrepayStatus(), PayConsts.PAY_STATUS_DONE) && !NumberUtil
                    .isNullOrZero(orderWork.getPrepayAmount())) {
                factAmount = factAmount + orderWork.getPrepayAmount().intValue();
            }
            if (Objects.equals(orderWork.getDepositStatus(), PayConsts.PAY_STATUS_DONE) && !NumberUtil
                    .isNullOrZero(orderWork.getDepositAmount())) {
                factAmount = factAmount + orderWork.getDepositAmount().intValue();
            }
            if (Objects.equals(orderWork.getMasterPayStatus(), PayConsts.PAY_STATUS_DONE) && !NumberUtil
                    .isNullOrZero(orderWork.getMasterAmount())) {
                factAmount = factAmount + orderWork.getMasterAmount().intValue();
            }
//            smsMap.put("amount", MoneyUtil.parseToYuanStr(orderWork.getTotalAmount() - factAmount));
            smsMap.put("amount", MoneyUtil.parseToYuanStr(orderWork.getTotalAmount()));
            smsMap.put("product_name", orderProduct.getProductName());
            smsMap.put("charge_time", DateUtil.getNowFormatted());
        }

        WeChatMessageDTO weChatMessage = WeChatMessageDTO.builder()
                .orderId(orderId)
                .openId(openId)
                .objectId(String.valueOf(sendUserId))
                .thirdAppId(orderThirdAppBind.getThirdAppId())
                .params(JSON.toJSONString(smsMap))
                .channelId(String.valueOf(orderWork.getChannelId()))
                .cityId(String.valueOf(orderWork.getCityId()))
                .build();
        return weChatMessage;
    }

    /**
     * 处理模板消息发送参数
     *
     * @param params
     * @return
     */
    protected Map<String, String> handleWeChatSendParams(SendMessageParams params) {
        // 关于"null"参数，已经和消息系统沟通好，如果多个连续参数在一起，但是其中某个参数不存在，可以用"null"特殊字符串代替
        // 下单 {$product_name}  {$duty_time} {$user_telephone}
        // 领单 {$product_name}  {$duty_time} {$master_name}   {$late_yesno}（传-->，工程师超过预约时间60分钟上门，订单可享受20元减免，并认准计价器报价）
        // 上门 {$productName}，  {$master_name}  {$order_id}   {$visit_time}  特殊 言而有信订单【{$complete_code}
        // 计价器定价/计价器变更   {$productName}， {$order_id}   {$visit_time}
        // 定金待支付，完成待支付  {$order_id}  {$amount}  {$order_time}-下单时间
        // 完成  {$total_amount} -- 有优惠附加，已为您优惠 xx  {$product_name}  {$complete_time}
        // 保修卡 {$warranty_id} ：{$useful_days}天
        // 延保消息 {$warranty_id} ：{$days}  {$end_time}
        // 取消  {$productName}， {$order_id}
        // 退款成功 $refund time}，{$order number}，{$refund products}，{$refund amount}
        // 获得提醒 $remark $

        // 迟到安抚不发送微信
        if (Objects.equals(MessageConsts.ZMN_MSG_RULEID_VISIT_TIME_OUT, params.getRuleId())) {
            return null;
        }

        Map<String, String> smsMap = new HashMap<>();
        OrderWork orderWork = params.getOrderWork();
        OrderDetail orderDetail = params.getOrderDetail();
        OrderProduct orderProduct = getProduct(params.getOrderId());
        // 2.工程师是否迟到减免
        boolean isLateOrder = NumberUtil.isNotNullOrZero(orderWork.getDiscountActivityId());

        // 上门节点，计价器3.0 不发送
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_MASTER_VISIT, params.getRuleId()) &&
                Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE, orderWork.getServItemType())) {
            logger.info("订单号【{}】计价器3.0不推送 ruleId={}，phone={} ", params.getOrderId(), params.getRuleId(), params.getTelephone());
            return null;
        }

        // 活动提醒数据
        if (Objects.equals(MessageConsts.ZMN_MSG_RULEID_ACTIVITY_REMINDER, params.getRuleId())) {
//            smsMap.put("name","活动提醒-测试");
//            smsMap.put("phone_number","13800000000");
//            smsMap.put("remark","欢迎参加");
//            smsMap.put("life_time",DateUtil.toString(DateUtil.getNowDeferMinutes(30)));
            smsMap.put("order_id",String.valueOf(params.getOrderId()));

            return smsMap;
        }

        // 通用内容
        if (StringUtils.isNotBlank(orderWork.getMasterName())) {
            smsMap.put("master_name", orderWork.getMasterName());
        }

        // 3、增加参数{$Privacy_trumpet}，取订单绑定的工程师的隐私小号；
        if (Objects.equals(orderDetail.getBindStatus(), OrderConsts.BIND_STATUS_BIND) &&
                StringUtils.isNotBlank(orderDetail.getBindTelephone())) {
            smsMap.put("privacy_trumpet", orderDetail.getBindTelephone());
        } else {
            smsMap.put("privacy_trumpet", "null");
        }

        if (Objects.nonNull(orderWork.getVisitTime())) {
            smsMap.put("visit_time", DateUtil.toString(orderWork.getVisitTime(), "yyyy年MM月dd日 HH:mm"));
            smsMap.put("home_time", DateUtil.toString(orderWork.getVisitTime(), "yyyy年MM月dd日 HH:mm"));
            smsMap.put("charge_time", DateUtil.toString(orderWork.getVisitTime(), "yyyy年MM月dd日 HH:mm"));
        }
        if (Objects.nonNull(orderWork.getCompleteTime())) {
            smsMap.put("complete_time", DateUtil.toString(orderWork.getCompleteTime(), "yyyy年MM月dd日 HH:mm"));
        }

        smsMap.put("order_id", String.valueOf(params.getOrderId()));
        smsMap.put("product_name", orderProduct.getShowCategName());
        smsMap.put("user_telephone", orderDetail.getTelephone());
        smsMap.put("order_time", DateUtil.toString(orderWork.getReceiveTime(), "yyyy年MM月dd日 HH:mm"));
        smsMap.put("duty_time", DateUtil.toString(orderWork.getDutyTime(), "yyyy年MM月dd日 HH:mm"));
        smsMap.put("public_name", StringUtils.replace(params.getThirdAppName(), "公众号", ""));


        // {$contact_time}：于xx时间上午
        // 下单时间为20:00-24:00：取下单日期+1天，传参文案【于xx日上午】
        // 下单时间为0:00-8:00：取下单日期，传参文案【于xx日上午】
        // 下单时间为8:00-20:00：传空
        //（格式：11月20日 19时20分）
        int hh = Integer.parseInt(DateUtil.toString(orderWork.getReceiveTime(), "HH"));
        if(hh >= 20){
            smsMap.put("contact_time", String.format("于%s上午", DateUtil.toString(DateUtil.addDays(DateUtil.getNow(), 1), "dd日")));
        } else if(hh < 8) {
            smsMap.put("contact_time", String.format("于%s上午", DateUtil.getNowFormatted("dd日")));
        } else {
            smsMap.put("contact_time", "null");
        }

        List<Integer> completeRules = Lists.newArrayList(MessageRuleIdConsts.ZMN_MSG_RULEID_COMPLETE, MessageRuleIdConsts.CNHB_MSG_RULEID_COMPLETE);
        if (completeRules.contains(params.getRuleId())) {
            // 服务价格
            double totalAmount = MoneyUtil.parseToYuan(orderWork.getTotalAmount());
            // 服务价格
            String totalAmountStr = String.format("%.2f元", totalAmount);
            if (!NumberUtil.isNullOrZero(orderWork.getDiscountAmount())) {
                double disAmount = AmountUtil.fen2Yuan(orderWork.getDiscountAmount()).doubleValue();
                totalAmountStr = String.format("%.2f元（已为您优惠：%.2f元）", totalAmount, disAmount);
            }
            smsMap.put("total_amount", totalAmountStr);
            smsMap.put("remark", totalAmountStr);
            smsMap.put("time",DateUtil.toString(Optional.ofNullable(orderWork.getCompleteTime()).orElse(DateUtil.getNow()),
                    "yyyy年MM月dd日 HH:mm"));

            if (!isMemberUser(params.getSendUserId())) {
               smsMap.put("content",COMPLETE_CONTENT_NORMAL);
            } else {
                smsMap.put("content",COMPLETE_CONTENT_MEMBER);
            }
        }

        // 节点特殊处理：保修卡 保修卡延保节点参数
//        if (Objects.equals(params.getNodeMark(), OrderLogConsts.ORDER_LOG_TYPE_WARRANTY) || Objects.equals(params.getNodeMark(), OrderLogConsts.ORDER_LOG_TYPE_UPDATE_WARRANTY)) {
//            // 查看主库获取保修卡信息
//            WarrantyVO warrantyVO = orderWarrantyBService.findWarrantyVOByOrderId(orderWork.getOrderId());
//            if (Objects.nonNull(warrantyVO)) {
//                smsMap.put("warranty_id", warrantyVO.getCode());
//                smsMap.put("useful_days", String.valueOf(warrantyVO.getPeriod()));
//                smsMap.put("end_time", DateUtil.toString(warrantyVO.getExpiredTime()));
//                smsMap.put("warranty_code", getStrEnCode(warrantyVO.getCode()));
//            }
//        }

        // 规则特殊处理：延保消息处理
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_WARRANTY_CARD_ADD, params.getRuleId()) && StringUtils.isNotBlank(params.getRemark())) {
            Map<String, String> remarkMap = getOtherParamsMap(params.getOrderId(), params.getRemark());
            String warrantyAddDay = "null";
            if (Objects.nonNull(remarkMap)) {
                warrantyAddDay = remarkMap.get("warrantyAddDay");
            }
            smsMap.put("days", warrantyAddDay);
        }

        // 提前付
        boolean isAdvancePay = false;
        // 判断提前付，先取订单，没有取试点配置
        if (Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_ADVANCE_PAY, orderWork.getServItemType())) {
            isAdvancePay = true;
        } else if (!Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE, orderWork.getServItemType())) {
            // 兼容老数据，上线一段时间后可以删除
            if (NumberUtil.isNotNullOrZero(orderProduct.getTariffId())) {
                // 判断价格表 1服务价格，2计价器价格，3提前支付价格
                ResponseDTO<TariffDRO> responseDTO = tariffRemoteService.getById(orderProduct.getTariffId());
                isAdvancePay = responseDTO.isSuccess() && Objects.nonNull(responseDTO.getData()) && Objects.equals(3, responseDTO.getData().getTariffType());
            } else {
                // 判断提前付试点
                PilotCheckQuery build = PilotCheckQuery
                        .builder()
                        .pilotTypeId(PilotTypeEnum.PAY_ADVANCE.getId())
                        .channelId(orderWork.getChannelId())
                        .cityId(orderWork.getCityId())
                        .servCategId(orderWork.getServCategId())
                        .categId(orderWork.getShowCategId())
                        .build();
                ResponseDTO<Boolean> responseDTO = pilotRemoteService.checkPilotByQuery(build);
                log.info("接单消息-提前付入参：{}, 出参：{}", JSON.toJSONString(orderWork), JSON.toJSONString(responseDTO));
                isAdvancePay = responseDTO.isSuccess() && responseDTO.getData();
            }
        }

        // 啄木鸟  分单、接单、计价器、节点微信消息
        smsMap.put("pay_yesno", "null");
        smsMap.put("pay_yesno_wx", "null");
        if (!isAdvancePay) {
            //  {$pay_yesno} 增加判断逻辑（非提前付订单且非会员）
            //  --非提前付、非预付款订单 → 点击https://d.zmn.cn/0tqsz 开通Z+钻卡会员，享全年10大特权，一单回本
            //  --提前付、预付款 → 空
            if (Objects.isNull(orderWork.getPrepayTime()) && !Objects.equals(orderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_MEMBER)) {
                smsMap.put("pay_yesno", "，开通Z+钻卡会员，享全年10大特权，一单回本");
                smsMap.put("pay_yesno_wx", "，开通Z+钻卡会员，享全年10大特权，一单回本");
            }
        }

        // 啄木鸟 领单、上门
        //  {$meter_yesno}：
        // 提前付--> 传空
        // 非提前付
        //      计价器2.0-->   ，为保障您的权益，请认准计价器报价
        //      计价器3.0-->   ，点击链接查看服务价格表
        // 非计价器-->   传空
        if (isAdvancePay) {
            // 提前付工单
            // smsMap.put("meter_yesno", "，请耐心等候，如有特殊情况请及时与师傅沟通");
            smsMap.put("meter_yesno_wx", "null");
            smsMap.put("meter_yesno", "null");
        } else if (Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_FAULT, orderWork.getServItemType())) {
            // 计价器2.0
            smsMap.put("meter_yesno_wx", "，为保障您的权益，请认准计价器报价");
            smsMap.put("meter_yesno", "，为保障您的权益，请认准计价器报价");
        } else if (Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE, orderWork.getServItemType())) {
            // 计价器3.0
            smsMap.put("meter_yesno_wx", "，点击链接查看服务价格表");
            smsMap.put("meter_yesno", "，点击链接查看服务价格表");
        } else {
            smsMap.put("meter_yesno_wx", "null");
            smsMap.put("meter_yesno", "null");
        }

        //    增加跳转链接传参
        //    {$jump_path}：跳转链接
        //    计价器2.0-->  微信小程序订单详情页
        //    计价器3.0-->  跳转订单对应商品详情页（李悦）
        //    非计价器-->   微信小程序订单详情页
        if(Objects.equals(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE, orderWork.getServItemType())) {
            // 计价器3.0，传前台产品ID
            smsMap.put("jump_path", String.format(productDetailWechatQuotation3Url, orderWork.getShowProductId()));
        } else {
            // 计价器2.0 和 其它
            smsMap.put("jump_path", String.format(orderDetailWechatUrl, orderWork.getOrderId()));
        }

        // 是否有迟到补偿
        if (isLateOrder) {
            smsMap.put("late_yesno", "，若上门延误，服务费减免20元");
            smsMap.put("late_yesno_wx", "，若上门延误，服务费减免20元");
        } else {
            smsMap.put("late_yesno", "null");
            smsMap.put("late_yesno_wx", "null");
        }

        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_MASTER_VISIT, params.getRuleId())) {
            // 三日退
            smsMap.put("three_days", "null");
            if (orderAllowRefund(orderWork)) {
                smsMap.put("three_days", "，若服务不达标，3天无理由退款，请您放心消费，监督工程师服务");
            }
        }

        // 特殊处理报价确认
        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_QUOTATION_CONFIRM, params.getRuleId())) {
            Integer quotationId = getQuotationIdByOrderId(orderWork.getOrderId());
            if (NumberUtil.isNullOrZero(quotationId)) {
                logger.info("#oms#sendQuotationByUpdateTemplate 订单号{},未找到报价id", orderWork.getOrderId());
                return null;
            }
            smsMap.put("quotation_id", String.valueOf(quotationId));
        }
       // boolean threeDays = orderAllowRefund(orderWork);

        // 规则特殊处理：言而有信保内订单
        if (Objects.equals(MessageRuleIdConsts.YEYX_MSG_RULEID_COMPLETE_TYPE_IN, params.getRuleId())) {
            String featureCode = EncodeUtil.getFeatureCode(orderWork.getWorkId(), 4);
            smsMap.put("complete_code", featureCode);
        }

        // 退款成功
        if (Objects.equals(MessageConsts.ZMN_MSG_RULEID_SERVICE_REFUND_SUCCESS, params.getRuleId())) {
            smsMap.put("refund time", DateUtil.toString(orderWork.getRefundTime()));
            smsMap.put("order number", String.valueOf(orderWork.getOrderId()));
            smsMap.put("refund products", orderProduct.getShowCategName());
            double refundAmount = MoneyUtil.parseToYuan(orderWork.getRefundAmount() + Math.abs(Optional.ofNullable(orderWork.getDiscountPrepayAmount()).orElse(0)));
            if (NumberUtil.isNullOrZero(refundAmount)) {
                return null;
            }
            smsMap.put("refund amount", String.format("%.2f元", refundAmount));
        }

        if (Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_TAKE, params.getRuleId())) {
            double masterTemperature = ThreadLocalRandom.current().nextDouble(36.0, 37.0);
            smsMap.put("master_temperature", String.format("%.1f", masterTemperature));
        }
        // 工程师健康信息
        if(Objects.equals(MessageRuleIdConsts.ZMN_MSG_RULEID_TAKE, params.getRuleId()) || Objects.equals(MessageConsts.ZMN_MSG_RULEID_RETAKE, params.getRuleId())){
            String masterHealthInfo = "null";
            if(NumberUtil.isNotNullOrZero(orderWork.getMasterId())){
                ResponseDTO<EngineerHealthLogoDRO> healthLogoResponseDTO= engineerHealthListRemoteService.getDisplayHealthLogoByEngineerId(orderWork.getMasterId());
                if(Objects.nonNull(healthLogoResponseDTO) && healthLogoResponseDTO.isSuccess() && Objects.nonNull(healthLogoResponseDTO.getData())){
                    if(!healthLogoResponseDTO.getData().getGetVaccine() && healthLogoResponseDTO.getData().getBodyTemperature()){
                        masterHealthInfo = "（工程师体温正常）";
                    }
                    if(healthLogoResponseDTO.getData().getGetVaccine() && healthLogoResponseDTO.getData().getBodyTemperature()){
                        masterHealthInfo = "（工程师已接种疫苗，体温正常）";
                    }
                }
            }
            smsMap.put("master_health_info", masterHealthInfo);
        }

        // 变量为空处理
        super.setParamsDefaultIfNull(smsMap);

        return smsMap;
    }


    /**
     * 当前用户是否关注公众号
     * subscribe 这个字段，1，表示关注，0表示没关注
     *
     * @param openId
     * @return
     */
    protected boolean isUserSubscribe(Long orderId, String openId, String appId) {
        try {
            log.info("订单号={},判断当前用户是否关注公众号入参openId={},appId={}", orderId, openId, appId);
            ResponseDTO<WeixinUserInfoDRO> resp = privateQrCodeListRemoteService.getWeChatUserInfo(openId, appId);
            log.info("订单号={},判断当前用户是否关注公众号getWeChatUserInfo出参【{}】", orderId, resp);
            if (resp.isSuccess() && Objects.nonNull(resp.getData())) {
                Integer subscribe = resp.getData().getSubscribe();
                return Objects.equals(subscribe, 1);
            }
        } catch (Exception ex) {
            log.error(String.format("订单号%s，判断当前用户是否关注公众号接口getWeChatUserInfo异常了:%s", orderId, ex.getMessage()), ex);
            return false;
        }
        return false;
    }

    /**
     * 获取报价id
     *
     * @param orderId
     */
    protected Integer getQuotationIdByOrderId(Long orderId) {
        ResponseDTO<Integer> quotationResp = null;
        try {
            quotationResp = quotationListRemoteService.checkHaveQuotation(orderId);
            logger.info("#oms#checkHaveQuotation#检查订单是否有报价入参orderId={},出参数={}", orderId, quotationResp);
            if (!quotationResp.isSuccess()) {
                logger.info("#oms#checkHaveQuotation#获取报价信息orderId={}失败", orderId);
                return 0;
            }
        } catch (Exception ex) {
            logger.error(String.format("订单号%s，检查订单是否有报价接口checkHaveQuotation异常了:%s", orderId, ex.getMessage()), ex);
            return 0;
        }
        return quotationResp.getData();
    }

    /**
     * 判断是否为会员
     * @param userId
     * @return
     */
    protected boolean isMemberUser(Long userId) {

        if (NumberUtil.isNullOrZero(userId)) {
            return false;
        }

        // 会员单判断
        logger.info("#MessageWeChatTemplateService#isSendCompleteMessage#check member，userId=[{}]",
                userId);
        ResponseDTO<UserDetailDRO> userDetailDROResponseDTO = userListRemoteService.getUserDetailById(
                userId, false);
        if (!userDetailDROResponseDTO.isSuccess() || Objects.isNull(userDetailDROResponseDTO.getData()) ||
                NumberUtil.isNullOrZero(userDetailDROResponseDTO.getData().getPassId())) {
            return false;
        }

        ResponseDTO<MemberDRO> memberDROResponseDTO = memberListRemoteService.getMemberById(
                userDetailDROResponseDTO.getData().getPassId());
        logger.info("#MessageWeChatTemplateService#isSendCompleteMessage#Get Member userId=[{}], passId=[{}],出参=[{}]",
                userId, userDetailDROResponseDTO.getData().getPassId(), JSON.toJSONString(memberDROResponseDTO));
        if (!memberDROResponseDTO.isSuccess() || Objects.isNull(memberDROResponseDTO.getData()) ||
                !Objects.equals(memberDROResponseDTO.getData().getStatus(), com.zmn.consts.GlobalConsts.YES)) {
            return false;
        }

        return true;
    }

}
